//
//  ListManager.m
//  YoucApp
//
//  Created by Liam on 12-10-14.
//  Copyright 2012 __MyCompanyName__. All rights reserved.
//

#import "ListManager.h"
#import "YoucApi.h"
#import "UserManager.h"
#import "Util.h"
#import <CmnFunc.h>

@interface ListManager()

@property (nonatomic, retain) id taskId;

- (void)processGameList:(NSArray *)list param:(id)param error:(NSError *)error;
- (void)processGameServerList:(NSArray *)list param:(id)param error:(NSError *)error;

- (void)saveGameList:(NSArray *)list;
- (NSArray *)loadGameList;

- (void)cacheGameList:(NSArray *)list withParam:(LMListParam *)param;
- (NSArray *)getCachedGameListWithParam:(LMListParam *)param;

- (void)cacheAttentionList:(NSArray *)list withParam:(LMAttentionListParam *)param;
- (NSArray *)getCachedAttentionListWithParam:(LMAttentionListParam *)param;

- (void)cacheServerList:(NSArray *)list withParam:(LMServerListParam *)param;
- (NSArray *)getCachedServerListWithParam:(LMServerListParam *)param;

- (void)cacheRecommendList:(NSArray *)list;
- (NSArray *)getCachedRecommendList;

@end

@implementation ListManager

OBJC_IMPL_SINGLETON(ListManager);

- (void)cancelPrevTask
{
//    if (self.taskId)
//    {
//        [[YoucApi instance] cancelTask:self.taskId];
//        self.taskId = nil;
//    }
}

- (void)getAllList:(LMListParam *)param forceLoad:(BOOL)forceLoad
{
    [self cancelPrevTask];
	
	[[UserManager instance] fillObjectWithSession:param];
	
	param.noticationName = LMGetAllListDidFinishedNotification;
	
	NSArray *cacheList = [self getCachedGameListWithParam:param];
	if (cacheList && cacheList.count)
	{
		[self processGameList:cacheList param:param error:nil];
	}
    else
	{
		self.taskId = [[YoucApi instance] getGameList:param context:param delegate:self];
	}
}

- (void)getRecommendList:(LMListParam *)param forceLoad:(BOOL)forceLoad
{
	[self cancelPrevTask];
	
	param.noticationName = LMGetRecommendListDidFinishedNotification;

	NSArray *cacheList = [self getCachedRecommendList];
	if (cacheList && cacheList.count)
	{
		[self processGameList:cacheList param:param error:nil];
	}
    else
	{
		self.taskId = [[YoucApi instance] getRecommendList:param delegate:self];
	}
}

- (void)getAttentionList:(LMAttentionListParam *)param forceLoad:(BOOL)forceLoad
{
	[self cancelPrevTask];
	
	[[UserManager instance] fillObjectWithSession:param];
	
	param.noticationName = LMGetAttentionListDidFinishedNotification;
	
	NSArray *cacheList = [self getCachedAttentionListWithParam:param];
	if (cacheList && cacheList.count)
	{
		[self processGameList:cacheList param:param error:nil];
	}
    else
	{
		self.taskId = [[YoucApi instance] getAttentionList:param context:param delegate:self];
	}
}

- (void)searchGames:(LMSearchGamesParam *)param
{
	[[UserManager instance] fillObjectWithSession:param];
	
	[[YoucApi instance] searchGames:param context:param delegate:self];
}

- (void)getGameServerList:(LMServerListParam *)param forceLoad:(BOOL)forceLoad
{
	NSArray *cacheList = [self getCachedServerListWithParam:param];
	if (cacheList && cacheList.count)
	{
		[self processGameServerList:cacheList param:param error:nil];
	}
    else
	{
		[[YoucApi instance] getGameServerList:param context:param delegate:self];
	}
}

#define POST_NOTIFICATIONNAME							@"POST_NOTIFICATIONNAME"
#define POST_NOTIFICATIONSENDER							@"POST_NOTIFICATIONSENDER"
#define POST_USERINFO                                   @"POST_USERINFO"

- (void)postOnMainThread:(NSDictionary *)dict
{
    NSString *notificationName = [dict objectForKey:POST_NOTIFICATIONNAME];
    id notificationSender = [dict objectForKey:POST_NOTIFICATIONSENDER];
    NSDictionary *userInfo = [dict objectForKey:POST_USERINFO];
	
	// 显示错误
	[Util showToastIfNeededWithAPIError:[userInfo objectForKey:LMErrorKey]];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:notificationSender userInfo:userInfo];
}

- (void)postOnMainThreadNotificationName:(NSString *)notificationName object:(id)notificationSender userInfo:(NSDictionary *)userInfo
{
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, POST_NOTIFICATIONNAME, notificationSender, POST_NOTIFICATIONSENDER, userInfo, POST_USERINFO, nil];
    
    [self performSelectorOnMainThread:@selector(postOnMainThread:) withObject:dict waitUntilDone:NO];
}

- (void)processGameList:(NSArray *)list param:(id)param error:(NSError *)error
{
	NSDictionary *postUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:param, LMListParamKey, list, LMRESULT, error, LMErrorKey, nil];
	
	NSString *noticationName = LMGetAllListDidFinishedNotification;
	if ([param respondsToSelector:@selector(noticationName)])
	{
		NSString *tmp = [param noticationName];
		if (tmp && [tmp length])
			noticationName = tmp;
	}
	
    [self postOnMainThreadNotificationName:noticationName object:self userInfo:postUserInfo];
}

#pragma mark YADelegateGame
- (void)getGameListResponse:(id)task respGameList:(YARespGameList *)respGameList
{
	// save cache
	if ([respGameList.context isKindOfClass:[LMListParam class]])
	{
		if ([[respGameList.context noticationName] isEqualToString:LMGetRecommendListDidFinishedNotification])
		{
			[self cacheRecommendList:respGameList.list];
		}
		else
		{
			[self cacheGameList:respGameList.list withParam:respGameList.context];
		}
	}
	else if ([respGameList.context isKindOfClass:[LMAttentionListParam class]])
	{
		[self cacheAttentionList:respGameList.list withParam:respGameList.context];
	}
	
    [self processGameList:respGameList.list param:respGameList.context error:respGameList.error];
}

- (void)searchGamesResponse:(id)task respGameList:(YARespGameList *)respGameList
{
	NSDictionary *postUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:respGameList.context, LMListParamKey, respGameList.error, LMErrorKey, respGameList.list, LMRESULT, nil];
	
	NSString *noticationName = LMSearchGamesDidFinishedNotification;
	
    [self postOnMainThreadNotificationName:noticationName object:self userInfo:postUserInfo];
}

- (void)processGameServerList:(NSArray *)list param:(id)param error:(NSError *)error
{
	NSDictionary *postUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:param, LMListParamKey, list, LMRESULT, error, LMErrorKey, nil];
    [self postOnMainThreadNotificationName:LMGetServerListDidFinishedNotification object:self userInfo:postUserInfo];
}

- (void)getGameServerListResponse:(id)task respGameServerList:(YARespGameServerList *)respGameServerList
{
	// save cache
	[self cacheServerList:respGameServerList.list withParam:respGameServerList.context];
	
    [self processGameServerList:respGameServerList.list param:respGameServerList.context error:respGameServerList.error];
}

#pragma mark -
#pragma mark cache game list

- (NSString *)gameListCacheFilePath
{
	NSString *path = [Util appDataDirectory];
	
	path = [path stringByAppendingPathComponent:@"cachelistgame.plist"];
	
	return path;
}

- (void)saveGameList:(NSArray *)list 
{
	[NSKeyedArchiver archiveRootObject:list toFile:[self gameListCacheFilePath]];
}

- (NSArray *)loadGameList
{
	return [NSKeyedUnarchiver unarchiveObjectWithFile:[self gameListCacheFilePath]];
}

- (void)cacheGameList:(NSArray *)list withParam:(LMListParam *)param
{
	if (list && list.count)
	{
		NSArray *cacheList = list;
		
		if (param.start != 0)
		{
			cacheList = [self loadGameList];
			if (cacheList.count == param.start)
			{
				cacheList = [cacheList arrayByAddingObjectsFromArray:list];
			}
		}
		
		[self saveGameList:cacheList];
	}
}

- (NSArray *)getCachedGameListWithParam:(LMListParam *)param
{
	if ([CmnFunc checkCanUseNetwork] || param.start != 0)
	{
		return nil;
	}

	return [self loadGameList];
}

#pragma mark -
#pragma mark cache attention list

- (NSString *)gameAttentionListCacheFilePath
{
	NSString *path = [Util currentUserAppDataDirectory];
	
	path = [path stringByAppendingPathComponent:@"cachelistattention.plist"];
	
	return path;
}

- (void)saveAttentionList:(NSArray *)list
{
	[NSKeyedArchiver archiveRootObject:list toFile:[self gameAttentionListCacheFilePath]];
}

- (NSArray *)loadAttentionList
{
	return [NSKeyedUnarchiver unarchiveObjectWithFile:[self gameAttentionListCacheFilePath]];
}

- (void)cacheAttentionList:(NSArray *)list withParam:(LMAttentionListParam *)param
{
	if (list && list.count)
	{
		[self saveAttentionList:list];
	}
}

- (NSArray *)getCachedAttentionListWithParam:(LMAttentionListParam *)param
{
	if ([CmnFunc checkCanUseNetwork])
	{
		return nil;
	}
	
	return [self loadAttentionList];
}

#pragma mark -
#pragma mark cache server list

- (NSString *)gameServerListCacheFilePathWithGame:(NSString *)gameId;
{
	NSString *path = [Util currentUserAppDataDirectory];
	
	path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"cachelistgameserver_%@.plist", gameId]];
	
	return path;
}

- (void)saveServerList:(NSArray *)list withGame:(NSString *)gameId
{
	[NSKeyedArchiver archiveRootObject:list toFile:[self gameServerListCacheFilePathWithGame:gameId]];
}

- (NSArray *)loadServerListWithGame:(NSString *)gameId
{
	return [NSKeyedUnarchiver unarchiveObjectWithFile:[self gameServerListCacheFilePathWithGame:gameId]];
}

- (void)cacheServerList:(NSArray *)list withParam:(LMServerListParam *)param
{
	if (list && list.count)
	{
		NSArray *cacheList = list;
		
		if (param.start != 0)
		{
			cacheList = [self loadServerListWithGame:param.gameId];
			if (cacheList.count == param.start)
			{
				cacheList = [cacheList arrayByAddingObjectsFromArray:list];
			}
		}
		
		[self saveServerList:cacheList withGame:param.gameId];
	}
}

- (NSArray *)getCachedServerListWithParam:(LMServerListParam *)param
{
	if ([CmnFunc checkCanUseNetwork] || param.start != 0)
	{
		return nil;
	}
	
	return [self loadServerListWithGame:param.gameId];
}


#pragma mark -
#pragma mark cache recommend list

- (NSString *)gameRecommendListCacheFilePath
{
	NSString *path = [Util currentUserAppDataDirectory];
	
	path = [path stringByAppendingPathComponent:@"cachelistrecommend.plist"];
	
	return path;
}

- (void)saveRecommendList:(NSArray *)list
{
	[NSKeyedArchiver archiveRootObject:list toFile:[self gameRecommendListCacheFilePath]];
}

- (NSArray *)loadRecommendList
{
	return [NSKeyedUnarchiver unarchiveObjectWithFile:[self gameRecommendListCacheFilePath]];
}

- (void)cacheRecommendList:(NSArray *)list
{
	if (list && list.count)
	{
		[self saveRecommendList:list];
	}
}

- (NSArray *)getCachedRecommendList
{
	if ([CmnFunc checkCanUseNetwork])
	{
		return nil;
	}
	
	return [self loadRecommendList];
}

@end
